//
//  TimelyInformation.m
//  SolarSeek
//
//  Created by Erick Fejta on 05/02/04.
//  Copyright 2005 Erick Fejta. All rights reserved.
//

#import "TimelyInformation.h"

@interface TimelyInformation (Private)
- (void)scheduleTest;
- (void)testValidity;
@end


@implementation TimelyInformation
- (id)initWithInfo:(id)i validForSeconds:(NSTimeInterval)s {
	if(self = [super init]) {
		info = [i retain];
		_dateValidated = nil;
		_durationValid = s;
		popped = NO;
		[self refresh];
	}
	return self;
}

+ (id)timelyInformation:(id)i validForSeconds:(NSTimeInterval)s {
	TimelyInformation *tf = [[TimelyInformation alloc] initWithInfo:i validForSeconds:s];
	return [tf autorelease];
}

- (unsigned)hash {
	return [info hash];
}

- (BOOL)isEqual:(id)obj {
	return [obj isKindOfClass:[TimelyInformation class]] && [[obj info] isEqual:info];
}

- (void)dealloc { 
	[_dateValidated release];
	_dateValidated = nil;
	_durationValid = 0;
//	NSLog(@"DEALLOC: timely info.");
	[info release];
	info = nil;
	[super dealloc];
}

- (id)info { return info; }
- (BOOL)isValid { return _dateValidated && [_dateValidated timeIntervalSinceNow]*-1 < _durationValid; }
- (BOOL)valid { return [self isValid]; }

- (void)invalidate {
	_durationValid = 0;
	[self testValidity];
}

- (void)refresh { 
	[self willChangeValueForKey:@"dateValidated"];
	[_dateValidated release];
	_dateValidated = [[NSDate alloc] init];
	[self scheduleTest];
	[self didChangeValueForKey:@"dateValidated"];
}

- (void)testValidity {
	[self retain];
	[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(testValidity) object:nil];
	if([self isValid] == NO && popped == NO) {
		popped = YES;
		[self willChangeValueForKey:@"info"];
		[self willChangeValueForKey:@"valid"];
		[info release];
		info = nil;
		[self didChangeValueForKey:@"valid"];
		[self didChangeValueForKey:@"info"];
	}
	else if(_durationValid > 0) [self scheduleTest];
	[self autorelease];
}


- (void)scheduleTest {
	[self performSelectorOnMainThread:@selector(scheduleTestOnMainThread) withObject:nil waitUntilDone:NO];
}

- (void)scheduleTestOnMainThread {
	if(_durationValid > 0) {
		[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(testValidity) object:nil];
		[self performSelector:@selector(testValidity) withObject:nil afterDelay:_durationValid];
	}
	else
		[self testValidity];
}
		

- (NSTimeInterval)secondsRemaining { return [_dateValidated timeIntervalSinceNow] + _durationValid; }
- (void)setDateExpired:(NSDate *)date {
	[self willChangeValueForKey:@"durationValid"];
	[self willChangeValueForKey:@"dateExpired"];
	_durationValid = [date timeIntervalSinceDate:_dateValidated];
	[self didChangeValueForKey:@"durationValid"];
	[self didChangeValueForKey:@"dateExpired"];
	[self scheduleTest];
}

- (NSDate *)dateExpired {
	return [_dateValidated addTimeInterval:_durationValid];
}

- (NSDate *)dateValidated { return _dateValidated; }
- (NSTimeInterval)durationValid { return _durationValid; }
@end
